using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;

public class StatesHandler : MonoBehaviour
{
	
	private static StatesHandler instance;
 
	public static StatesHandler Instance
	{
		get
		{
			if (instance == null)
			{
				instance = new GameObject("StatesHandler").AddComponent<StatesHandler>();
				StatesHandler.initialize();
			}
 
			return instance;
		}
	}
	
	private LinkedList<TState> _states = new LinkedList<TState>();
	private LinkedListNode<TState> currentState;
	private bool activated = false;
	private string statesPath;
	
	public static UILabel stateLabel;
	public static UITexture stateImage;
	public static UIButton stateApply;
	public static UIButton stateCancel;
	public static UIButton stateDelete;
	public static UIButton statePrev;
	public static UIButton stateNext;
	
	void Awake(){
		
		statesPath = Application.persistentDataPath+"/States/";
		DirectoryInfo statesDir = new DirectoryInfo(statesPath);
		statesDir.Create();
		
		//clean states
		foreach (FileInfo file in statesDir.GetFiles()){
    		file.Delete(); 
		}
		foreach (DirectoryInfo dir in statesDir.GetDirectories()){
    		dir.Delete(true); 
		}

	}
	
	public static void initialize(){
		stateLabel = GameObject.Find("StateLabel").GetComponent<UILabel>();
		stateImage = GameObject.Find("StateImage").GetComponent<UITexture>();
		stateApply = GameObject.Find("ApplyStateButton").GetComponent<UIButton>();
		stateCancel = GameObject.Find("CancelStateButton").GetComponent<UIButton>();
		statePrev = GameObject.Find("PrevStateButton").GetComponent<UIButton>();
		stateNext = GameObject.Find("NextStateButton").GetComponent<UIButton>();
		stateDelete = GameObject.Find("DeleteStateButton").GetComponent<UIButton>();
	}
	
	public void showNext(){
		if(currentState.Next != null){
			currentState = currentState.Next;	
		}
		refreshDisplay();
	}
	
	public void showPrev(){
		if(currentState.Previous != null){
			currentState = currentState.Previous;	
		}
		refreshDisplay();
	}
	
	public void saveState(){	
		List<TAction> actions = new List<TAction>();
		
		foreach(GameObject o in LevelHandler.Instance.tangibles.Values){
			GPObject gpo = new GPObject(o);
			
			if(gpo.Type != ObjectType.LaserReceiver && gpo.Type != ObjectType.Unknown){
				if(gpo.Type == ObjectType.LaserGenerator){
					actions.Add(new TChangeColorAction(gpo,gpo));
				}else{
					actions.Add(new TAddAction(gpo));	
				}
			}			
		}
		
		int stamp = TimeStampUtils.GetTimeStamp();
		
		addState(new TState(stamp,actions));
		
		Application.CaptureScreenshot(statesPath+stamp+".png");

	}
	
	public void loadState(){
		THistory.Instance.loadState(currentState.Value);
		Activated = false;
		currentState = _states.Last;
	}
	
	public void deleteState(){
		TState toDelete = currentState.Value;
		if(currentState.Next != null){
			showNext();
		}else if(currentState.Previous != null){
			showPrev();
		}else{
			if(_states.Count == 0){
				currentState = null;
			}else{
				currentState = _states.Last;	
			}
				
			Activated = false;
			THistory.Instance.undoing = false;
			refreshDisplay();
		}
		
		_states.Remove(toDelete);
	}
	
	public void refreshDisplay(){
		if(activated){
			TweenPosition.Begin(stateLabel.gameObject,0.5f,new Vector3(5,-360,0));
			TweenPosition.Begin(stateApply.gameObject,0.5f,new Vector3(-350,380,0));
			TweenPosition.Begin(stateCancel.gameObject,0.5f,new Vector3(445,380,0));
			TweenPosition.Begin(stateDelete.gameObject,0.5f,new Vector3(300,380,0));
			
			if(currentState.Previous != null){
				TweenPosition.Begin(statePrev.gameObject,0.5f,new Vector3(-508,0,0));
			}else{
				TweenPosition.Begin(statePrev.gameObject,0.5f,new Vector3(-570,0,0));
			}
			
			if(currentState.Next != null){
				TweenPosition.Begin(stateNext.gameObject,0.5f,new Vector3(508,0,0));
			}else{
				TweenPosition.Begin(stateNext.gameObject,0.5f,new Vector3(570,0,0));
			}
				
			stateLabel.text = "il y a "+TimeStampUtils.GetSpan(currentState.Value.TimeStamp);
			
			WWW www = new WWW("file://"+statesPath+currentState.Value.TimeStamp+".png");
			
			Texture2D t = new Texture2D(1024,768);
			www.LoadImageIntoTexture(t);
			stateImage.mainTexture = t;
			stateImage.MakePixelPerfect();
			
			stateImage.transform.localScale = stateImage.transform.localScale * 1.04f;
			
			stateImage.enabled = true;

		}else{
			
			TweenPosition.Begin(stateLabel.gameObject,0.5f,new Vector3(5,-400,0));
			TweenPosition.Begin(stateApply.gameObject,0.5f,new Vector3(-350,480,0));
			TweenPosition.Begin(stateCancel.gameObject,0.5f,new Vector3(445,480,0));
			TweenPosition.Begin(stateDelete.gameObject,0.5f,new Vector3(300,480,0));
			
			TweenPosition.Begin(statePrev.gameObject,0.5f,new Vector3(-570,0,0));
			TweenPosition.Begin(stateNext.gameObject,0.5f,new Vector3(570,0,0));
			
			
			
			stateImage.enabled = false;
		}
	}
	
	public void addState(TState state){
		if(currentState != null){
			if(currentState.Value.TimeStamp.Equals(state.TimeStamp)){
				return;	
			}
		}
		
		if(_states.Count ==  10){
			_states.RemoveFirst();
		}
		
		_states.AddLast(state);
		currentState = _states.Last;
	}
	
	public void clear(){
		_states.Clear();
		currentState = null;
	}
	
	public bool hasStates(){
		return _states.Count != 0;	
	}
	
	public bool Activated {
		get {
			return this.activated;
		}
		set{
			activated = value;
		}
	}
	
}

